package com.star.rpc.serializer;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.star.rpc.modal.RpcRequest;
import com.star.rpc.modal.RpcResponse;

/**
 * packageName com.star.rpc.serializer
 *
 * @author zerostart
 * @className JsonSerializer
 * @date 2024/11/20
 * @description Json序列化器, 存在对象转换兼容性问题，比如Object数组在序列化后会丢失类型
 */

public class JsonSerializer implements Serializer {

    public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Override
    public <T> byte[] serialize(T object) throws Exception {
        return OBJECT_MAPPER.writeValueAsBytes(object);
    }

    @Override
    public <T> T deserialize(byte[] bytes, Class<T> clazz) throws Exception {
        T obj = OBJECT_MAPPER.readValue(bytes, clazz);
        if (obj instanceof RpcRequest) {
            return handleRequest((RpcRequest) obj, clazz);
        }
        if (obj instanceof RpcResponse) {
            return handleRequest((RpcResponse) obj, clazz);
        }

        return obj;
    }

    private <T> T handleRequest(RpcRequest request, Class<T> type) throws Exception {
        Class<?>[] parameterTypes = request.getParameterTypes();
        Object[] args = request.getArgs();
        // 循环处理每个参数
        for (int i = 0; i < parameterTypes.length; i++) {
            Class<?> clazz = parameterTypes[i];
            // 如果类型不同则重新处理一下类型
            if (!clazz.isAssignableFrom(args[i].getClass())) {
                byte[] argBytes = OBJECT_MAPPER.writeValueAsBytes(args[i]);
                args[i] = OBJECT_MAPPER.readValue(argBytes, clazz);
            }
        }
        return type.cast(request);
    }


    private <T> T handleRequest(RpcResponse response, Class<T> type) throws Exception {

        byte[] dataBytes = OBJECT_MAPPER.writeValueAsBytes(response);
        response.setData(OBJECT_MAPPER.readValue(dataBytes, type));

        return type.cast(response);
    }
}
